#ifndef __EXPR_H_
#define __EXPR_H_

/**
 * 抽象语法树结点的类别, 共3大类:
 * 与声明有关的、与表达式有关的、与语句有关的
 * NK:  Node Kind
*/
enum nodeKind
{
    NK_Literal = 1,
    NK_Label,
    NK_TypeQualifier,
    NK_EnumDeclaration,
    NK_ChoseDeclaration,
    NK_Declaration,
    NK_Expression
};

/**
    kind:    the kind of node
    next:    pointer to next node
    coord:    the coordinate of node
*/
#define AST_NODE_COMMON \
    enum nodeKind kind; \
    int line; \
    struct astNode *next;

typedef struct astNode {
    AST_NODE_COMMON
} *AstNode;

// TK_ID, TK_INTEGER, TK_FLOAT, TK_PAREN, TK_BRACE
typedef struct astLiteral {
    AST_NODE_COMMON
    int tk;
    const char *val;
    int valLen;
} *AstLiteral;

typedef union {
    const char *s;
    int i;
    double f;
} LiteralValue;

// TK_ID
typedef struct astLabel {
    AST_NODE_COMMON
    const char *name;
} *AstLabel;

#define TQ_SIGN     1
#define TQ_UNSIGN   2
#define TQ_BIG      1
#define TQ_LITTLE   2
// TK_SIGN, TK_UNSIGN, TK_BIG, TK_LITTLE,
// TK_ALIGN, TK_SIZE, TK_POS, TK_WHEN,
// TK_ENCODE, TK_DECODE, TK_PRINT, TK_EXPORT
typedef struct astTypeQualifier {
    AST_NODE_COMMON
    unsigned char sign : 2; // 2 max
    unsigned char sort : 2; // 2 max
    unsigned char size; // 64 max
    unsigned char align; // 128 max
    AstLiteral len;
    AstLiteral pos;
    AstLiteral when;
    AstLiteral encode;
    AstLiteral decode;
    AstLiteral print;
    const char *export;
} *AstTypeQualifier;

// TK_ENUM, TK_FIELD
typedef struct astEnumDeclaration {
    AST_NODE_COMMON
    const char *name;
    int val;
} *AstEnumDeclaration;

// TK_CHOSE
typedef struct astChoseDeclaration {
    AST_NODE_COMMON
    int val;
    int isDefault;
    AstNode expr;
} *AstChoseDeclaration;

enum BaseType {
    BT_Bit = 1,             // 1 bit
    BT_UChar, BT_SChar,     // 8 bit
    BT_UShort, BT_SShort,   // 16 bit
    BT_UInt, BT_SInt,       // 32 bit
    BT_ULong, BT_SLong,     // 64 bit
    BT_Float, BT_Double,    // 浮点类型
    BT_Struct, BT_Union,    // 组合体
    BT_Typedef,
    BT_UnAlign = 0x100,     // 未对齐
    BT_StaticArray = 0x200, // 静态数组
    BT_DynArray = 0x400     // 动态数组
};

// TK_TYPE
typedef struct astDeclaration {
    AST_NODE_COMMON
    const char *funcName;
    AstTypeQualifier ql;
    AstNode type;
    const char *name;
    AstLiteral array;
    int baseType;
} *AstDeclaration;

// TK_NUM, TK_DECIMAL, TK_ENUM, TK_FIELD, TK_STRUCT, TK_CHOSE,
// TK_LBRACKET, TK_TYPEDEF, TK_COMPILE
typedef struct astExpression {
    AST_NODE_COMMON
    const char *funcName;
    int tk;
    AstNode kids[2];
} *AstExpression;

#define CREATE_AST_NODE(p, k)   \
    ALLOC_CLR(p);                   \
    p->kind = NK_##k;           \
    p->line = TokenLine;

AstNode ParseSourceFile(void);

#endif
